<?php

namespace app\service;

use Exception;
use GuzzleHttp\Client;

class WechatService
{
    private $config;
    private $client;

    public function __construct()
    {
        $this->config = config('oauth.wechat');
        $this->client = new Client([
            'timeout' => 10,
            'verify' => false,
        ]);
    }

    /**
     * 获取用户信息
     */
    public function getUserInfo($code, $platform = 'mini')
    {
        if ($platform === 'mini') {
            return $this->getMiniUserInfo($code);
        } else {
            return $this->getWebUserInfo($code);
        }
    }

    /**
     * 小程序获取用户信息
     */
    private function getMiniUserInfo($code)
    {
        // 1. 通过code获取session_key和openid
        $response = $this->client->get('https://api.weixin.qq.com/sns/jscode2session', [
            'query' => [
                'appid' => $this->config['mini']['app_id'],
                'secret' => $this->config['mini']['app_secret'],
                'js_code' => $code,
                'grant_type' => 'authorization_code',
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['errcode'])) {
            throw new Exception('微信授权失败: ' . ($result['errmsg'] ?? '未知错误'));
        }

        return [
            'openid' => $result['openid'],
            'unionid' => $result['unionid'] ?? '',
            'session_key' => $result['session_key'],
            'nickname' => '', // 小程序需要前端传递用户信息
            'avatar' => '',
            'platform' => 'wechat_mini',
        ];
    }

    /**
     * 网页版获取用户信息
     */
    private function getWebUserInfo($code)
    {
        // 1. 通过code获取access_token
        $response = $this->client->get('https://api.weixin.qq.com/sns/oauth2/access_token', [
            'query' => [
                'appid' => $this->config['web']['app_id'],
                'secret' => $this->config['web']['app_secret'],
                'code' => $code,
                'grant_type' => 'authorization_code',
            ]
        ]);

        $tokenResult = json_decode($response->getBody()->getContents(), true);

        if (isset($tokenResult['errcode'])) {
            throw new Exception('微信授权失败: ' . ($tokenResult['errmsg'] ?? '未知错误'));
        }

        // 2. 通过access_token获取用户信息
        $response = $this->client->get('https://api.weixin.qq.com/sns/userinfo', [
            'query' => [
                'access_token' => $tokenResult['access_token'],
                'openid' => $tokenResult['openid'],
                'lang' => 'zh_CN',
            ]
        ]);

        $userResult = json_decode($response->getBody()->getContents(), true);

        if (isset($userResult['errcode'])) {
            throw new Exception('获取用户信息失败: ' . ($userResult['errmsg'] ?? '未知错误'));
        }

        return [
            'openid' => $userResult['openid'],
            'unionid' => $userResult['unionid'] ?? '',
            'nickname' => $userResult['nickname'] ?? '',
            'avatar' => $userResult['headimgurl'] ?? '',
            'access_token' => $tokenResult['access_token'],
            'refresh_token' => $tokenResult['refresh_token'],
            'expires_at' => date('Y-m-d H:i:s', time() + $tokenResult['expires_in']),
            'platform' => 'wechat_web',
            'extra_data' => [
                'sex' => $userResult['sex'] ?? 0,
                'province' => $userResult['province'] ?? '',
                'city' => $userResult['city'] ?? '',
                'country' => $userResult['country'] ?? '',
            ]
        ];
    }

    /**
     * 刷新access_token
     */
    public function refreshAccessToken($refreshToken)
    {
        $response = $this->client->get('https://api.weixin.qq.com/sns/oauth2/refresh_token', [
            'query' => [
                'appid' => $this->config['web']['app_id'],
                'grant_type' => 'refresh_token',
                'refresh_token' => $refreshToken,
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['errcode'])) {
            throw new Exception('刷新Token失败: ' . ($result['errmsg'] ?? '未知错误'));
        }

        return $result;
    }

    /**
     * 验证access_token是否有效
     */
    public function checkAccessToken($accessToken, $openid)
    {
        $response = $this->client->get('https://api.weixin.qq.com/sns/auth', [
            'query' => [
                'access_token' => $accessToken,
                'openid' => $openid,
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        return $result['errcode'] === 0;
    }

    /**
     * 获取微信小程序码
     */
    public function getMiniQrcode($scene, $page = '', $width = 430)
    {
        // 先获取access_token
        $accessToken = $this->getMiniAccessToken();

        $response = $this->client->post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}", [
            'json' => [
                'scene' => $scene,
                'page' => $page,
                'width' => $width,
                'auto_color' => false,
                'line_color' => ['r' => 0, 'g' => 0, 'b' => 0],
            ]
        ]);

        return $response->getBody()->getContents();
    }

    /**
     * 获取小程序access_token
     */
    private function getMiniAccessToken()
    {
        // 这里应该实现缓存机制
        $response = $this->client->get('https://api.weixin.qq.com/cgi-bin/token', [
            'query' => [
                'grant_type' => 'client_credential',
                'appid' => $this->config['mini']['app_id'],
                'secret' => $this->config['mini']['app_secret'],
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['errcode'])) {
            throw new Exception('获取access_token失败: ' . ($result['errmsg'] ?? '未知错误'));
        }

        return $result['access_token'];
    }
}